package com.chrray.position.service.web.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chrray.position.domain.*;
import com.chrray.position.domain.dto.DictionaryDTO;
import com.chrray.position.entity.position.FdJobPostingsExe;
import com.chrray.position.enums.YesNoEnum;
import com.chrray.position.enums.app.*;
import com.chrray.position.mapper.position.*;
import com.chrray.position.pojo.dto.web.FdJobPostingsApplyDto;
import com.chrray.position.pojo.dto.web.FdJobPostingsFavDto;
import com.chrray.position.pojo.dto.web.FdJobPostingsImportDto;
import com.chrray.position.pojo.response.UploadDeviceVO;
import com.chrray.position.pojo.vo.web.FdJobPostingsExeVo;
import com.chrray.position.service.web.WFdJobPostingsService;
import com.chrray.position.util.result.ResponseResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static com.chrray.position.util.result.ResponseResults.fail;
import static com.chrray.position.util.result.ResponseResults.success;

/**
 * @author lm
 * @date 2024/08/28 22:15
 */
@Service
@AllArgsConstructor
@Slf4j
public class WFdJobPostingsServiceImpl extends ServiceImpl<FdJobPostingsMapper, FdJobPostings> implements WFdJobPostingsService {
    @Resource
    private FdJobPostingsMapper mapper;
    @Resource
    private FdJobWorkerRelMapper fdJobWorkerRelMapper;
    @Resource
    private FdJobSubcategoryMapper fdJobSubcategoryMapper;
    @Resource
    private FdJobCategoryMapper fdJobCategoryMapper;
    @Resource
    private SysAreaMapper sysAreaMapper;


    @Override
    public IPage pageList(FdJobPostingsExe entity) {
        LambdaQueryWrapper<FdJobPostings> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getJobName()), FdJobPostings::getJobName, entity.getJobName());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getStatusSearch()), FdJobPostings::getStatus, entity.getStatusSearch());
        queryWrapper.ge(!ObjectUtils.isEmpty(entity.getStartTime()), FdJobPostings::getPublishTime, entity.getStartTime());
        queryWrapper.le(!ObjectUtils.isEmpty(entity.getEndTime()), FdJobPostings::getPublishTime, entity.getEndTime());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getStatus()), FdJobPostings::getStatus, entity.getStatus());
        queryWrapper.eq(FdJobPostings::getCheckStatus, FdJobCheckStateEnum.IN_PROGRESS);
        queryWrapper.orderByDesc(FdJobPostings::getPublishTime);
        log.info("分页前参数：{}，{}", entity.getPageNum(), entity.getPageSize());
        IPage page = new Page();
        page.setCurrent(entity.getPageNum());
        page.setSize(entity.getPageSize());
        log.info("分页：{}", JSONObject.toJSONString(page));
        IPage<FdJobPostings> pageList = this.page(page, queryWrapper);
        pageList.getRecords().stream().forEach(
                fdJobPostings -> {
                    FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
                    fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
                }
        );
        return pageList;
    }

    @Override
    public IPage pageCheckList(FdJobPostingsExe entity) {
        LambdaQueryWrapper<FdJobPostings> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getJobName()), FdJobPostings::getJobName, entity.getJobName());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getStatusSearch()), FdJobPostings::getStatus, entity.getStatusSearch());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getCheckStatus()), FdJobPostings::getCheckStatus, entity.getCheckStatus());
        queryWrapper.ge(!ObjectUtils.isEmpty(entity.getStartTime()), FdJobPostings::getPublishTime, entity.getStartTime());
        queryWrapper.le(!ObjectUtils.isEmpty(entity.getEndTime()), FdJobPostings::getPublishTime, entity.getEndTime());
        queryWrapper.ne(FdJobPostings::getStatus, FdJobStateEnum.WAIT.getValue());
//        queryWrapper.orderByDesc(FdJobPostings::getCheckStatus);
        queryWrapper.last(" order by check_status,publish_time desc");
        IPage page = entity.getPage();
        IPage<FdJobPostings> pageList = this.page(page, queryWrapper);
        pageList.getRecords().stream().forEach(
                fdJobPostings -> {
                    FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
                    fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
                }
        );
        return pageList;
    }

    @Override
    public IPage FdJobPostings(FdJobPostingsExe entity) {
        LambdaQueryWrapper<FdJobPostings> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getJobName()), FdJobPostings::getJobName, entity.getJobName());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getStatusSearch()), FdJobPostings::getStatus, entity.getStatusSearch());
        queryWrapper.eq(!ObjectUtils.isEmpty(entity.getStatus()), FdJobPostings::getStatus, entity.getStatus());
        queryWrapper.ge(!ObjectUtils.isEmpty(entity.getStartTime()), FdJobPostings::getPublishTime, entity.getStartTime());
        queryWrapper.le(!ObjectUtils.isEmpty(entity.getEndTime()), FdJobPostings::getPublishTime, entity.getEndTime());
        queryWrapper.eq(FdJobPostings::getUserId, entity.getUserId());
        queryWrapper.orderByDesc(FdJobPostings::getPublishTime);
        IPage page = entity.getPage();
        IPage<FdJobPostings> pageList = this.page(page, queryWrapper);
        pageList.getRecords().stream().forEach(
                fdJobPostings -> {
                    LambdaQueryWrapper<FdJobWorkerRel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(FdJobWorkerRel::getJobId, fdJobPostings.getId());
                    lambdaQueryWrapper.eq(FdJobWorkerRel::getState, FdWorkJobStateEnum.WAIT.getValue());
                    Integer waitEmployNum = fdJobWorkerRelMapper.selectCount(lambdaQueryWrapper);

                    LambdaQueryWrapper<FdJobWorkerRel> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper1.eq(FdJobWorkerRel::getJobId, fdJobPostings.getId());
                    lambdaQueryWrapper1.eq(FdJobWorkerRel::getState, FdWorkJobStateEnum.EMPLOYED.getValue());
                    Integer employedNum = fdJobWorkerRelMapper.selectCount(lambdaQueryWrapper1);
                    if (fdJobPostings.getStatus().equals(FdJobStateEnum.MATCHING.getValue())) {
                        fdJobPostings.setEmployedNum(employedNum);
                        fdJobPostings.setWaitCompNum(0);
                    } else {
                        fdJobPostings.setEmployedNum(0);
                        fdJobPostings.setWaitCompNum(employedNum);
                    }
                    fdJobPostings.setWaitEmployNum(waitEmployNum);
                    FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
                    fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
                }
        );
        return pageList;

    }

    @Override
    public ResponseResult check(FdJobPostings job) {

        FdJobPostings fdJobPostings = baseMapper.selectById(job.getId());
        if (ObjectUtils.isEmpty(fdJobPostings)) {
            return fail("职位不存在");
        }

        if (!fdJobPostings.getCheckStatus().equals(FdJobCheckStateEnum.PENDING.getValue())) {
            return fail("职位不是待审核");
        }
        fdJobPostings.setCheckStatus(job.getCheckStatus());
        fdJobPostings.setCheckDetail(job.getCheckDetail());
        if (job.getCheckStatus().equals(FdJobCheckStateEnum.IN_PROGRESS.getValue())) {
            fdJobPostings.setStatus(FdJobStateEnum.MATCHING.getValue());
        } else {
            fdJobPostings.setStatus(FdJobStateEnum.REJECTED.getValue());
        }

        this.updateById(fdJobPostings);
        return success();

    }

    @Override
    public IPage pageMyPostingsApplyList(FdJobPostingsApplyDto entity) {

        IPage page = entity.getPage();
        IPage<FdJobPostingsExeVo> pageList = baseMapper.pageMyPostingsApplyList(page, entity.getJobName(), entity.getJobState(), entity.getStartTime(), entity.getEndTime(), entity.getUserId());
        pageList.getRecords().stream().forEach(
                fdJobPostings -> {
                    FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
                    fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
                }
        );
        return pageList;
    }

    @Override
    public IPage pageMyPostingsFavList(FdJobPostingsFavDto entity) {

        IPage page = entity.getPage();
        IPage<FdJobPostings> pageList = baseMapper.pageMyPostingsFavList(page, entity.getJobName(), entity.getUserId());
        pageList.getRecords().stream().forEach(
                fdJobPostings -> {
                    FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
                    fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
                }
        );
        return pageList;
    }

    @Override
    public ResponseResult<List<SysArea>> districtSelection(Long code) {
        if (ObjectUtils.isEmpty(code)) {
            code = 0L;
        }
        if (!code.equals(0L)) {
            code = this.getCode(code);
        }
        LambdaQueryWrapper<SysArea> sysAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysAreaLambdaQueryWrapper.eq(SysArea::getPid, code);

        List<SysArea> dictionaryDTOS = sysAreaMapper.selectList(sysAreaLambdaQueryWrapper);
        return success(dictionaryDTOS);
    }

    private Long getCode(Long code) {
        String c = code.toString();

        if (c.length() >= 12) {
            return code;
        } else {
            String s = "";
            for (int i = 0; i < (12 - c.length()); i++) {
                s = s + "0";
            }
            c = c + s;
            return Long.valueOf(c);
        }
    }

    @Override
    public ResponseResult<FdJobPostings> selectById(Long id) {

        FdJobPostings fdJobPostings = baseMapper.selectById(id);
        if (!ObjectUtils.isEmpty(fdJobPostings.getJobCategory())) {
            FdJobSubcategory fdJobSubcategory = fdJobSubcategoryMapper.selectById(fdJobPostings.getJobCategory());
            fdJobPostings.setJobCategoryName(ObjectUtils.isEmpty(fdJobSubcategory) ? "" : fdJobSubcategory.getName());
        }

        if (!ObjectUtils.isEmpty(fdJobPostings.getDistrictId())) {

            LambdaQueryWrapper<SysArea> sysAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();

            sysAreaLambdaQueryWrapper.eq(SysArea::getDistrictId, Long.valueOf(fdJobPostings.getDistrictId()));


            sysAreaLambdaQueryWrapper.last(" limit 1");
            SysArea sysArea = sysAreaMapper.selectOne(sysAreaLambdaQueryWrapper);
            fdJobPostings.setSysArea(sysArea);
        }

        return success(fdJobPostings);
    }

    @Override
    public void publishJob(FdJobPostings job) {
        job.setStatus(FdJobStateEnum.MATCHING.getValue());
        job.setStaTime(new Date());
        job.setCheckStatus(FdJobCheckStateEnum.IN_PROGRESS.getValue());
        job.setAdminPublished(YesNoEnum.YES.getCode());
        if (job.getIsNewPeasant().equals(YesNoEnum.YES.getCode())) {
            job.setJobType(FdJobType.NEW_FARMER.getValue());
        }
        baseMapper.insert(job);
    }

    @Override
    public ResponseResult<UploadDeviceVO> importAdjective(MultipartFile file) {

        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        try {

            List<FdJobPostingsImportDto> list = ExcelImportUtil.importExcel(file.getInputStream(),
                    FdJobPostingsImportDto.class, params);
            log.info("导入数据：{}", JSONObject.toJSONString(list));
            list.forEach(
                    jobExcel -> {
                        FdJobPostings newJob = new FdJobPostings();
                        BeanUtils.copyProperties(jobExcel, newJob);
                        newJob.setAdminPublished(YesNoEnum.YES.getCode());
                        newJob.setStatus(FdJobStateEnum.WAIT.getValue());
                        newJob.setStaTime(new Date());
                        newJob.setPublishTime(new Date());
                        newJob.setCheckStatus(FdJobCheckStateEnum.IN_PROGRESS.getValue());
                        if (!ObjectUtils.isEmpty(jobExcel.getCalcMethodDesc())) {
                            newJob.setCalcMethod(FdSalaryCalcMethodEnum.getByInfo(jobExcel.getCalcMethodDesc()).getValue());
                        }
                        if (!ObjectUtils.isEmpty(jobExcel.getJobTypeDesc())) {
                            newJob.setJobType(FdJobType.getByInfo(jobExcel.getJobTypeDesc()).getValue());
                        }
                        if (!ObjectUtils.isEmpty(jobExcel.getGenderDsec())) {
                            newJob.setGender(FdGenderEnum.getByInfo(jobExcel.getGenderDsec()).getValue());
                        }
                        if (!ObjectUtils.isEmpty(jobExcel.getRequiresExperienceDesc())) {
                            newJob.setRequiresExperience(YesNoEnum.getByInfo(jobExcel.getRequiresExperienceDesc()).getCode());
                        }
                        if (!ObjectUtils.isEmpty(jobExcel.getIsNewPeasantDesc())) {
                            newJob.setIsNewPeasant(YesNoEnum.getByInfo(jobExcel.getIsNewPeasantDesc()).getCode());
                            if (newJob.getIsNewPeasant().equals(YesNoEnum.YES.getCode())) {
                                newJob.setJobType(FdJobType.NEW_FARMER.getValue());
                            }
                        }


                        baseMapper.insert(newJob);
                    }
            );


            return success();
        } catch (Exception e) {
            log.error("导入职位错误", e);
            return fail("导入职位错误");
        }
    }

    @Override
    public void update(FdJobPostings job) {
        FdJobPostings fdJobPostings = baseMapper.selectById(job.getId());
        if (fdJobPostings.getStatus().equals(FdJobStateEnum.WAIT.getValue())) {
            job.setStatus(FdJobStateEnum.MATCHING.getValue());
        }
        baseMapper.updateById(job);
    }
}
